package product

import (
	"context"
	"strings"

	"mall/common/ctxdatax"
	"mall/common/globalkey"
	"mall/common/resultx"
	"mall/service/backend/common/utils/pointy"
	"mall/service/forum/api/internal/logic/util"
	"mall/service/forum/api/internal/svc"
	"mall/service/forum/api/internal/types"
	"mall/service/forum/api/internal/utils/parse"
	"mall/service/product/rpc/productclient"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetPackageListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewGetPackageListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPackageListLogic {
	return &GetPackageListLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *GetPackageListLogic) GetPackageList(req *types.ProductListReq) (*types.PackageListInfo, error) {
	userId := ctxdatax.GetUserId(l.ctx)
	if userId == 0 {
		return nil, resultx.NewErrCode(resultx.TOKEN_EXPIRE_ERROR)
	}

	page, pageSize := parse.ParsePageInfo(
		req.Current,
		req.PageSize,
		l.svcCtx.Config.Query.DefaultAmount,
		l.svcCtx.Config.Query.MaxAmount,
	)

	var preload string = "product:Id,Title,Slug,Excerpt,Status"
	var eagerLoad string = "product:productMedia,productVariation,productVariationMeta,total"
	preload += ";productMedia:Id,Uid,Url,Thumbnail,Order"
	preload += ";productVariation:Id,GemPrice,RetailPrice,CounterPrice"
	preload += ";productVariationMeta:mediaId,mediaUrl,sku,skuKey"
	var filters []string
	var preFilter string = "Slug,equalTo:Gems"
	var preFilterEntity string = "productTerm"
	filters = append(filters, "virtual,equalTo:1")
	if req.Filter != nil && len(strings.TrimSpace(*req.Filter)) > 0 {
		filterMap := util.GetFilterMap(strings.TrimSpace(*req.Filter))
		for key, val := range filterMap {
			switch key {
			case "sticky": // todo: 使用场景未知
				filters = append(filters, "sticky,equalTo:" + val)
			}
		}
	}

	var sorter *string
	if req.Sorter != nil {
		sorter =  pointy.GetPointer(strings.TrimSpace(*req.Sorter))
	}
	var platformId uint32 = globalkey.ThirdPartyPlatformWechatMini

	res, err := l.svcCtx.ProductRpc.GetProductList(l.ctx, &productclient.BaseListReq{
		Offset:          uint32((page-1)*pageSize),
		Limit:           uint32(pageSize),
		Preload:         pointy.GetPointer(preload),
		EagerLoad:       pointy.GetPointer(eagerLoad),
		Filter:          pointy.GetPointer(strings.Join(filters, ";")),
		Sorter:          sorter,
		PreFilterEntity: pointy.GetPointer(preFilterEntity),
		PreFilter:       pointy.GetPointer(preFilter),
		VisitorId:       pointy.GetPointer(userId),
		PlatformId:      pointy.GetPointer(platformId),
	})
	if err != nil {
		return nil, err
	}

	var hasNextPage bool
	var hasPreviousPage bool
	if res.HasNextPage != nil && *res.HasNextPage > 0 {
		hasNextPage = true
	}
	if res.HasPreviousPage != nil && *res.HasPreviousPage > 0 {
		hasPreviousPage = true
	}
	resp := &types.PackageListInfo{
		BaseListInfo: types.BaseListInfo{
			Total:           res.Total,
			Current:         page,
			PageSize:        pageSize,
			HasNextPage:     hasNextPage,
			HasPreviousPage: hasPreviousPage,
		},
	}

	if len(res.List) > 0 {
		for _, v := range res.List {
			var photos []*types.MediaInfo
			if len(v.Media) > 0 {
				for _, m := range v.Media {
					var url string
					if m.Url != nil && len(*m.Url) > 0 {
						url = *m.Url
					}
					if len(url) == 0 && m.Uri != nil && len(*m.Uri) > 0 {
						url = *m.Uri
					}
					var thumbnail *bool
					if m.Thumbnail != nil {
						thumbnail = pointy.GetPointer(*m.Thumbnail > 0)
					}
					photos = append(photos, &types.MediaInfo{
						Uid:       m.Uid,
						Id:        m.Id,
						Url:       pointy.GetPointer(url),
						Thumbnail: thumbnail,
						AltText:   m.AltText,
						MetaData:  m.MetaData,
						Order:     m.Order,
					})
				}
			}

			var skuId *uint64
			var gemPrice *string
			var retailPrice *string
			var counterPrice *string
			if len(v.Skus) > 0 {
				for _, sv := range v.Skus {
					skuId        = sv.Id
					gemPrice     = sv.GemPrice
					retailPrice  = sv.RetailPrice
					counterPrice = sv.CounterPrice
					break
				}
			}

			var statusText *string
			if v.Status != nil {
				statusText = pointy.GetPointer(util.GetStatusText(int32(*v.Status)))
			}

			resp.List = append(resp.List, &types.PackageInfo{
				Id:           v.Id,
				SkuId:        skuId,
				Title:        v.Title,
				Slug:         v.Slug,
				Excerpt:      v.Excerpt,
				ContentHtml:  v.Content,
				Status:       v.Status,
				StatusText:   statusText,
				Media:        photos,
				GemPrice:     gemPrice,
				RetailPrice:  retailPrice,
				CounterPrice: counterPrice,
			})
		}
	}

	return resp, nil
}
